import { _decorator, Component, Enum, error, js, warn } from 'cc';
import { EventBus } from '../core/EventBus';
import { Logger } from '../lib/Logger';
import { CoreModule } from './BaseModule';
const { ccclass, property } = _decorator;

enum ViewHideMode {
    Destroy,
    Active,
}

const Group = { id: 'BaseView', name: 'Settings', displayOrder: -Infinity, style: 'section' };

@ccclass('BaseView')
export class BaseView<T extends CoreModule = CoreModule> extends Component {
    public static ViewHideMode = ViewHideMode;

    @property
    private _hideMode = ViewHideMode.Destroy;
    @property({
        group: Group,
        type: Enum(ViewHideMode),
        tooltip: '关闭模式\n1、destroy: 销毁UI并释放对应的所有资源\n2、active: 缓存UI并加速下次的打开速度',
    })
    public get hideMode() {
        if (this.viewName.indexOf('Page') == 0)
            return ViewHideMode.Destroy;
        return this._hideMode;
    }
    public set hideMode(value) {
        if (this.viewName.indexOf('Page') == 0 && value !== ViewHideMode.Destroy) {
            warn('Page只能使用Destroy模式');
            return;
        }
        this._hideMode = value;
    }

    @property
    private _shadow = true;
    @property({
        group: Group,
        tooltip: '是否需要底层遮罩',
        visible(this: BaseView) {
            if (this.viewName.indexOf('Page') == 0) return false;
            if (this.viewName.indexOf('Paper') == 0) return false;
            return true;
        }
    })
    public get shadow() {
        if (this.viewName.indexOf('Page') == 0) return false;
        if (this.viewName.indexOf('Paper') == 0) return false;
        return this._shadow;
    }
    protected set shadow(value) {
        if (value) {
            if (this.viewName.indexOf('Page') == 0) {
                this.log('Page不可以设置底层遮罩');
                return;
            }
            if (this.viewName.indexOf('Paper') == 0) {
                this.log('Paper不可以设置底层遮罩');
                return;
            }
        }

        this._shadow = value;
    }

    // 事件
    private _base_event = new EventBus();

    // 类名
    private _base_view_name = js.getClassName(this);
    public get viewName() {
        return this._base_view_name;
    }

    // 模块
    private _module: T = null;
    public get module(): T {
        return this._module;
    }

    // 初始化流程
    public static init(view: BaseView, module: CoreModule): void {
        view._module = module;
        view.initialize();
    }

    private initialize(): void {
        // 初始化逻辑
    }

    // Show流程
    protected beforeShow(data: any = null): Promise<void> {
        return Promise.resolve();
    }

    protected onShow(data: any = null): void {
        // 显示逻辑
    }

    public static async innerShow(
        view: BaseView,
        data: any = null,
        onShow: (() => void) | null = null,
        onHide: ((data: any) => void) | null = null,
        beforeShow: (() => void) | null = null
    ): Promise<void> {
        view.log('BeforeShow');
        return view.beforeShow(data)
            .then(() => {
                beforeShow?.();

                // 注册onHide事件
                view._base_event.once('onHide', onHide);

                // 触发引擎生命周期
                view.node.active = true;

                // 触发onShow
                view.log('onShow');
                view.onShow(data);

                onShow?.();
            });
    }

    protected beforeHide(): void {
        // 隐藏前逻辑
    }

    protected onHide(): any {
        return null;
    }

    // Hide流程
    public static innerHide(view: BaseView, onHide: ((data: any) => void) | null = null): boolean {
        try {
            view.beforeHide();
        } catch (err) {
            view.error(err as string);
            return false;
        }

        const result = view.onHide();

        try {
            // 先触发onShow中注册的回调
            view._base_event.emit('onHide', result);
            // 再触发参数中的回调
            onHide?.(result);
        } catch (err) {
            error(err);
        }
        return true;
    }

    /**打印日志 */
    private get log(): Function {
        return Logger.create('log', '#4682b4', `[${this.viewName}] LOG`);
    }
    /**打印警告 */
    private get warn(): Function {
        return Logger.create('warn', '#ff7f50', `[${this.viewName}] WARN`);
    }
    /**打印错误 */
    private get error(): Function {
        return Logger.create('error', '#ff4757', `[${this.viewName}] ERROR`);
    }
}